package main

import "fmt"

/*
T 为类型形参
int|float32为类型约束
被包裹在中括号中被称为 类型形参列表
在类型定义中，带 类型形参的类型， 称为泛型类型

*/

type Slice[T int | float32 | float64] []T

/*
KEY VALUE 称为类型形参
其后面跟的 int|string 为类型约束
包裹在中括号里被称为 类型形参列表
*/

type MyMap[KEY int | string, VALUE float32 | int] map[KEY]VALUE

type MyStruct[T int | string] struct { // 泛型类型的结构体

	Name string
	Date T
}

// 泛型接口
type IPrintData[T int | float32 | string] interface {
	Print(data T)
}

// 泛型通道
type MyChan[T int | string] chan T

// 类型形参的相互套用
// T 的类型决定着 S 的类型
type WowStruct[T int | float32, S []T] struct {
	Data     S
	MaxValue T
	MinValue T
}

/*
type CommonType[T int | string] T
类型形参不可独立存在
*/

func main() {

	var a Slice[int] = []int{1, 2, 3} // 泛型类型不能直接拿来使用，必须传入类型实参将其确定为具体的类型才可， 传入类型实参确定类型的操作被称为实例化
	fmt.Println(a)

	var b Slice[float32] = []float32{0.1, 0.2}
	fmt.Println(b)

	var c MyMap[int, int] = map[int]int{ // 两个类型 int 都为类型实参
		1: 1,
		2: 3,
	}
	fmt.Println(c)

	var d MyStruct[string] = MyStruct[string]{ // 需要对类型进行实例化
		Name: "zyl",
		Date: "888",
	}
	fmt.Println(d)

	ws := WowStruct[int, []int]{
		Data:     []int{1, 2},
		MaxValue: 100,
		MinValue: 1,
	}
	fmt.Println(ws)

}
